/*
 * Copyright © 2017 eqxiu.com 北京中网易企秀科技有限公司  All rights reserved.
 */
package cn.hermit.data.xmljson;

import cn.hermit.data.json.model.JSONDocument;
import cn.hermit.data.json.model.JSONObject;

import java.util.Iterator;
import java.util.Map.Entry;

/**
 * Constants and utility of <a href="http://badgerfish.ning.com" target="_blank">Badgerfish</a> convention. 
 * 
 * <p>
 * As there is an overkill and lost for white space in text node, the framework provides a loosen 
 * Badgerfish convention against the official Badgerfish. We called them loosen Badgerfish and strict Badgerfish.
 * </p>
 * 
 * @author Jack Gao (Chinese name : GAO JIANGUO, Email : linux.gjg@gmail.com)
 * @date 19 Jun, 2014
 */
public abstract class Badgerfish {

	/**
	 * Prefix in JSON Key for XML Attribute in Badgerfish.
	 * e.g. <pre>
	 * &lt;book name="book01" &gt;&lt;/book&gt; will be converted to {"book":{"@name":"book01"}}
	 * </pre>
	 * 
	 */
	public static final String KEY_PREFIX_ATTRIBUTE = "@";

	/**
	 * Prefix of order in JSON Key for same tags elements
	 * e.g. <pre>
	 * &lt;bookstore&gt;&lt;book name="book02" &gt;&lt;/book&gt;&lt;book name="book02" &gt;&lt;/book&gt;&lt;/bookstore&gt;
	 * will be converted to {"bookstore":{"book":{"@name":"book01"},"book#1":{"@name":"book02"}}}
	 * </pre>
	 * 
	 */
	public static final String KEY_PREFIX_ORDER = "#";

	/**
	 * JSON Key for XML text node
	 */
	public static final String KEY_TEXT = "$";

	/**
	 * JSON Key for XML CDATA node
	 */
	public static final String KEY_CDATA = "$$";
	
	/**
	 * JSON Key for XML name space key
	 */
	public static final String KEY_XMLNS = "@xmlns";

	/**
	 * Check if JSON Key is XML element tag
	 * @param key
	 * 		The JSON Key
	 * @return
	 */
	public static boolean isElementTag(String key) {
		return !isAttributeKey(key) && !isCDATAKey(key) && !isTextKey(key);
	}

	/**
	 * Check if JSON Key is XML attribute key.
	 * 
	 * @param key
	 * 		The JSON Key
	 * @return
	 */
	public static boolean isAttributeKey(String key) {
		return key.startsWith(Badgerfish.KEY_PREFIX_ATTRIBUTE);
	}

	/**
	 * Check if JSON Key indicates XML CDATA
	 * @param key
	 * 		The JSON key
	 * @return
	 */
	public static boolean isCDATAKey(String key) {
		return key.startsWith(Badgerfish.KEY_CDATA);
	}

	/**
	 * Check if JSON Key indicates XML Text
	 * @param key
	 * 		The JSON key
	 * @return
	 */
	public static boolean isTextKey(String key) {
		return !isCDATAKey(key) && key.startsWith(Badgerfish.KEY_TEXT);
	}

	/**
	 * Get Badgerfish style key from JSON object.
	 * 
	 * @param jo
	 * 		The JSON Object
	 * @param key
	 * 		Key in JSON Object
	 * @return
	 * 		Badgerfish style key 
	 */
	public static String getBadgerfishKey(JSONObject jo, String key) {
		int count = keySize(jo, key);
		if (count == 0) {
			return key;
		}
		return key + KEY_PREFIX_ORDER + count;
	}

	/**
	 * Get Non-Badgerfish style key from a Badgerfish style key
	 * @param key
	 * 		Badgerfish style key
	 * @return
	 * 		Non-Badgerfish style key
	 */
	public static String getNormalKey(String key) {
		if (key.startsWith(KEY_PREFIX_ATTRIBUTE)) {
			key = key.substring(1);
		}
		int i = key.indexOf(KEY_PREFIX_ORDER);
		if (i != -1) {
			key = key.substring(0, i);
		}
		return key;
	}

	/**
	 * Get count of the key from JSON Object.
	 * 
	 * @param jo
	 * 		The JSON Object
	 * @param key
	 * 		Key in JSON Object
	 * @return
	 * 		Count of the key
	 */
	public static int keySize(JSONObject jo, String key) {
		if (jo.size() == 0) {
			return 0;
		}
		int count = 0;
		Iterator<Entry<String, JSONDocument>> iter = jo.entryIterator();
		while (iter.hasNext()) {
			Entry<String, JSONDocument> entry = iter.next();
			String k = entry.getKey();
			int i = k.indexOf(KEY_PREFIX_ORDER);
			if (i != -1) {
				k = k.substring(0, i);
			}
			if (k.equals(key)) {
				count++;
			}
		}
		return count;
	}

}